﻿#include "NCTDialogLayUp.h"
#include "ui_NCTDialogLayUp.h"
#include "NCTDialogLayUpOwned.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsNCT.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsNCTLayUp.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsNCTRegularTrimLayer.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsNCTSeptum.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsNCTPerforated.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsNCTResistive.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbsMaterial.h"
#include <QMessageBox>
#include <QComboBox>
namespace GUI
{
    NCTDialogLayUp::NCTDialogLayUp(PhysicsDlgExecType type, int nctid/*=-1*/, QWidget* parent /*= nullptr*/)
        :AbstractMaterialDialog(type, parent)
    {
        _ui = new Ui::NCTDialogLayUp;
        _ui->setupUi(this);
        //获取声学包对象
        if ( _nctMgr && nctid > 0)
            _nct = dynamic_cast<Acoustics::FITKAcousticsNCTLayUp*>(_nctMgr->getDataByID(nctid));

        //默认选中第一个类型
        _ui->radioButton_Foam->setChecked(true);
        this->init();
    }

    NCTDialogLayUp::~NCTDialogLayUp()
    {
        if (_ui) delete _ui;
    }

    void NCTDialogLayUp::on_pushButton_OK_clicked()
    {
        if (!this->checkInput()) return;
        //要处理的对象
        Acoustics::FITKAcousticsNCTLayUp* layup = dynamic_cast<Acoustics::FITKAcousticsNCTLayUp*>(_nct);
        //创建与复制,创建新对象
        if (_execType == GUI::PhysicsDlgExecType::Create || _execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            layup = new Acoustics::FITKAcousticsNCTLayUp;
            _nctMgr->appendDataObj(layup);
        }
        if (!layup)return;
        //保存数据  
        layup->clear();
        layup->setDataObjectName(_ui->lineEdit_Name->text());
        for (int i = 0; i < _dataList.length(); i++)
        {
            if (!_dataList[i]) continue;
            layup->insertDataObj(i, _dataList[i]);
        }
        layup->setMaxFieldAngle(_ui->lineEdit_MaximumFieldAngle->text().toDouble());
        this->accept();
    }

    void NCTDialogLayUp::on_pushButton_Cancel_clicked()
    {
        this->reject();
    }

    void NCTDialogLayUp::on_pushButton_Delete_clicked()
    {
        //获取期选中的行
        int row = _ui->tableWidget->currentRow();
        if (row < 0)return;
        //删除行数据
        _ui->tableWidget->removeRow(row);
        //删除数据
        _dataList.removeAt(row - 1);
        refreshThicknessArea();
        refreshTableWidget();
    }

    void NCTDialogLayUp::on_pushButton_Edit_clicked()
    {
        int row = _ui->tableWidget->currentRow();
        if (row <= 0 || row > _dataList.size())return;
        auto data = _dataList[row-1];
        if (!data)return;
        GUI::NCTDialogLayUpOwned dlg(data);
        if (QDialog::Accepted == dlg.exec()) {
            refreshThicknessArea();
            refreshTableWidget();
        }
    }

    void NCTDialogLayUp::on_pushButton_Add_clicked()
    {
        auto type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::None;
        if (_ui->radioButton_Foam->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Foam;
        else if (_ui->radioButton_fiber->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Fiber;
        else if (_ui->radioButton_Gap->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Gap;
        else if (_ui->radioButton_Panel->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Panel;
        else if (_ui->radioButton_Septum->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Septum;
        else if (_ui->radioButton_Perforated->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Perforated;
        else if (_ui->radioButton_Resistive->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Resistive;

        Acoustics::FITKAcousticsNCTAbstractLayObj * newData{};
        switch (type) {
            case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Foam: 
            case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Fiber:
            case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Gap:
            case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Panel: {
                auto data = new Acoustics::FITKAcousticsNCTRegularTrimLayer;
                data->initType(type);
                newData = data;
                break;
            }
            case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Septum: {
                auto data = new Acoustics::FITKAcousticsNCTSeptum;
                newData = data;
                break;
            }
            case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Perforated: {
                auto data = new Acoustics::FITKAcousticsNCTPerforated;
                newData = data;
                break;
            }
            case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Resistive: {
                auto data = new Acoustics::FITKAcousticsNCTResistive;
                newData = data;
                break;
            }
        }
        if (!newData)return;
        GUI::NCTDialogLayUpOwned dlg(newData);
        if (QDialog::Accepted == dlg.exec()) {
            _dataList.append(newData);
            refreshThicknessArea();
            refreshTableWidget();
        }
    }

    void NCTDialogLayUp::on_pushButton_Insert_clicked()
    {
        int currentRow = _ui->tableWidget->currentRow();
        if (currentRow <= 0)return;
        auto type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::None;
        if (_ui->radioButton_Foam->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Foam;
        else if (_ui->radioButton_fiber->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Fiber;
        else if (_ui->radioButton_Gap->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Gap;
        else if (_ui->radioButton_Panel->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Panel;
        else if (_ui->radioButton_Septum->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Septum;
        else if (_ui->radioButton_Perforated->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Perforated;
        else if (_ui->radioButton_Resistive->isChecked())
            type = Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Resistive;

        Acoustics::FITKAcousticsNCTAbstractLayObj * newData{};
        switch (type) {
        case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Foam:
        case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Fiber:
        case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Gap:
        case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Panel: {
            auto data = new Acoustics::FITKAcousticsNCTRegularTrimLayer;
            data->initType(type);
            newData = data;
            break;
        }
        case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Septum: {
            auto data = new Acoustics::FITKAcousticsNCTSeptum;
            newData = data;
            break;
        }
        case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Perforated: {
            auto data = new Acoustics::FITKAcousticsNCTPerforated;
            newData = data;
            break;
        }
        case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Resistive: {
            auto data = new Acoustics::FITKAcousticsNCTResistive;
            newData = data;
            break;
        }
        }
        if (!newData)return;

        GUI::NCTDialogLayUpOwned dlg(newData);
        if (QDialog::Accepted == dlg.exec()) {     
            _dataList.insert(currentRow - 1, newData);
            refreshThicknessArea();
            refreshTableWidget();
        }
    }

    void NCTDialogLayUp::init()
    {
        if (_nctMgr == nullptr) return;
        //不可编辑，隐藏行号
        _ui->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
        _ui->tableWidget->verticalHeader()->setVisible(false);

        if (_execType == GUI::PhysicsDlgExecType::Create)
        {
            QString name = _nctMgr->checkName("New Treatment Lay-up");
            _ui->lineEdit_Name->setText(name);
            _ui->tableWidget->resizeColumnsToContents();
        }

        Acoustics::FITKAcousticsNCTLayUp* layup = dynamic_cast<Acoustics::FITKAcousticsNCTLayUp*>(_nct);
        if (!layup) return;
        // 设置各个属性的值
        _ui->lineEdit_Name->setText(layup->getDataObjectName());
        _ui->lineEdit_MaximumFieldAngle->setText(QString::number(layup->getMaxFieldAngle()));

        int dataCount = layup->getDataCount();
        _ui->tableWidget->setRowCount(dataCount);
        for (int i = 0; i < dataCount; i++)
        {
            Acoustics::FITKAcousticsNCTAbstractLayObj* layerData = layup->getDataByIndex(i);
            if (!layerData) continue;
            //复制一份数据
            Acoustics::FITKAcousticsNCTAbstractLayObj* newData = copyLayerData(layerData);
            _dataList.append(newData);
        }
        //填充表格数据
        refreshTableWidget();
        //填充面积厚度
        refreshThicknessArea();
        //复制,更新名称
        if (_execType == GUI::PhysicsDlgExecType::Duplicate)
        {
            QString text = QString("Copy of %1").arg(layup->getDataObjectName());
            _ui->lineEdit_Name->setText(text);
        }
    }

    bool NCTDialogLayUp::checkInput()
    {
        QString text1 = _ui->lineEdit_MaximumFieldAngle->text().trimmed();
        bool ok = false;
        text1.toDouble(&ok);
        if (!ok)
        {
            QMessageBox::critical(nullptr, tr("Critical"), tr("Please enter a number."));
            return false;
        }
        if (_nctMgr == nullptr) return false;
        //检查名称
        QString text = _ui->lineEdit_Name->text().trimmed();
        if (text != "") {
            QString newText = _nctMgr->checkName(text);
            if (text == newText) return true;
            //与自己重名
            if (_nctMgr->getDataByName(text) == _nct) return true;
        }
        QMessageBox::critical(nullptr, tr("Critical"), tr("Please enter a new Name."));
        return false;
    }

    Acoustics::FITKAcousticsNCTAbstractLayObj * NCTDialogLayUp::copyLayerData(Acoustics::FITKAcousticsNCTAbstractLayObj * data)
    {
        if (!data)return nullptr;
        Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType type = data->getNCTLayUpType();
        Acoustics::FITKAcousticsNCTAbstractLayObj* newData{};
        if (type == Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Foam ||
            type == Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Panel ||
            type == Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Gap ||
            type == Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Fiber)
        {
            //Fiber Foam Gap Panel
            newData = new Acoustics::FITKAcousticsNCTRegularTrimLayer;
            newData->copy(data);
        }
        else if (type == Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Septum){
            //隔离层 Septum
            newData = new Acoustics::FITKAcousticsNCTSeptum;
            newData->copy(data);
        }
        else if (type == Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Perforated){
            //多孔介质 Perforated
            newData = new Acoustics::FITKAcousticsNCTPerforated;
            newData->copy(data);
        }
        else if (type == Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Resistive){
            // 阻尼 Resistive
            newData = new Acoustics::FITKAcousticsNCTResistive;
            newData->copy(data);
        }
        return newData;
    }

    void NCTDialogLayUp::refreshTableWidget()
    {
        if (!_matMgr)return;
        //清空
        _ui->tableWidget->setRowCount(0);

        QString fluidMaterialName = tr("None");
        QString solidMaterialName = tr("None");
        double lossFactor = 0;
        double thickness = 0;
        int rowCount = _dataList.length();
        _ui->tableWidget->setRowCount(rowCount);
        for (int i = 0; i < rowCount; i++)
        {
            if (!_dataList[i]) continue;
            QString typeStr{};
            auto type= _dataList[i]->getNCTLayUpType();
            thickness = _dataList[i]->getThickness();
            switch (type)
            {
            case Acoustics::FITKAcousticsNCTAbstractLayObj::Foam:    typeStr = "Foam";
            case Acoustics::FITKAcousticsNCTAbstractLayObj::Fiber:   if (typeStr == "")typeStr = "Fiber";
            case Acoustics::FITKAcousticsNCTAbstractLayObj::Gap:     if (typeStr == "")typeStr = "Gap";
            case Acoustics::FITKAcousticsNCTAbstractLayObj::Panel: {
                // 泡沫、缝隙、实体和纤维类型
                auto regular = dynamic_cast<Acoustics::FITKAcousticsNCTRegularTrimLayer*>(_dataList[i]);
                if (!regular)continue;
                if (typeStr == "")typeStr = "Panel";
                Interface::FITKAbstractMaterial* fluidData = _matMgr->getDataByID(regular->getFluidMaterialID());
                if (fluidData) fluidMaterialName = fluidData->getDataObjectName();
                Interface::FITKAbstractMaterial* solidData = _matMgr->getDataByID(regular->getSolidMaterialID());
                if (solidData)solidMaterialName = solidData->getDataObjectName();
                lossFactor = regular->getLossFactor(); 
                break;
            }
            case Acoustics::FITKAcousticsNCTAbstractLayObj::Septum: {
                // 隔离类型
                typeStr= "Septum";
                break;
            }
            case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Perforated: {
                // 多孔类型
                typeStr = "Perforated";
                Acoustics::FITKAcousticsNCTPerforated* perforated = dynamic_cast<Acoustics::FITKAcousticsNCTPerforated*>(_dataList[i]);
                if (!perforated)continue;
                Interface::FITKAbstractMaterial* fluidData = _matMgr->getDataByID(perforated->getfluidMaterialID());
                if (fluidData) fluidMaterialName = fluidData->getDataObjectName();
                Interface::FITKAbstractMaterial* solidData = _matMgr->getDataByID(perforated->getMaterialID());
                if (solidData)solidMaterialName = solidData->getDataObjectName();
                break;
            }
            case Acoustics::FITKAcousticsNCTAbstractLayObj::NCTLayUpType::Resistive: {
                // 阻尼类型
                typeStr = "Resistive";
                break;
            }
            default: break;
            }
            _ui->tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));
            _ui->tableWidget->setItem(i, 1, new QTableWidgetItem(typeStr));
            _ui->tableWidget->setItem(i, 2, new QTableWidgetItem(solidMaterialName));
            _ui->tableWidget->setItem(i, 3, new QTableWidgetItem(fluidMaterialName));
            _ui->tableWidget->setItem(i, 4, new QTableWidgetItem(QString::number(thickness)));
            _ui->tableWidget->setItem(i, 5, new QTableWidgetItem(QString::number(lossFactor)));
            fluidMaterialName = tr("None");
            solidMaterialName = tr("None");
        }
        //自适应宽度
        _ui->tableWidget->resizeColumnsToContents();
        //结构侧和流体侧标记
        _ui->tableWidget->insertRow(0);
        int rowCounts = _ui->tableWidget->rowCount();
        _ui->tableWidget->setRowCount(rowCounts + 1);
        rowCounts = _ui->tableWidget->rowCount();
        QTableWidgetItem* item = new QTableWidgetItem(tr("Structre side"));
        item->setFlags(item->flags() & ~Qt::ItemIsSelectable & ~Qt::ItemIsEditable);
        _ui->tableWidget->setItem(0, 0, item);
        item = new QTableWidgetItem(tr("Fluid side"));
        item->setFlags(item->flags() & ~Qt::ItemIsSelectable & ~Qt::ItemIsEditable);
        _ui->tableWidget->setItem(rowCounts - 1, 0, item);
        _ui->tableWidget->setSpan(0, 0, 1, 6);
        _ui->tableWidget->setSpan(rowCounts - 1, 0, 1, 6);
    }

    void NCTDialogLayUp::refreshThicknessArea()
    {
        double thickness = 0.0;
        double massPerUnitArea = 0.0;
        for (int i = 0; i < _dataList.length(); i++)
        {
            if (!_dataList[i])continue;
            thickness = thickness + _dataList[i]->getThickness();
            massPerUnitArea = massPerUnitArea + _dataList[i]->getMassPerUnitArea();
        }
        _ui->lineEdit_TotalThickness->setText(QString::number(thickness));
        _ui->lineEdit_TotalMassperUnitAreaAngel->setText(QString::number(massPerUnitArea));
    }
}